﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace VidoopSecure
{
    public class ImageShield
    {
        private string _id;
        private int _length;
        private bool _orderMatters;
        private int _width;
        private int _height;
        private string _imageCodeColor;
        private string _image;
        private bool _attempted;
        private bool _authenticated;
        private string _xml;

        /// <summary>
        /// Imageshield Id
        /// </summary>
        public string Id 
        { 
            get { return _id; } 
            set { _id = value; } 
        }

        /// <summary>
        /// Number of categories that must be entered to solve the ImageShield.
        /// </summary>
        public int Length 
        { 
            get { return _length; } 
            set { _length = value; } 
        }

        /// <summary>
        /// Whether the categories must be entered in order.
        /// </summary>
        public bool OrderMatters 
        { 
            get { return _orderMatters; } 
            set { _orderMatters = value; } 
        }

        /// <summary>
        /// Width of the ImageShield in number of images.
        /// </summary>
        public int Width 
        { 
            get { return _width; } 
            set { _width = value; } 
        }

        /// <summary>
        /// Height of the ImageShield in number of images.
        /// </summary>
        public int Height 
        { 
            get { return _height; } 
            set { _height = value; } 
        }

        /// <summary>
        /// Color of the image code.
        /// </summary>
        public string ImageCodeColor 
        { 
            get { return _imageCodeColor; } 
            set { _imageCodeColor = value; } 
        }

        /// <summary>
        /// Url of ImageShield image to display to the user.
        /// </summary>
        public string Image 
        { 
            get { return _image; } 
            set { _image = value; } 
        }

        /// <summary>
        /// Has solution of this ImageShield already been attempted.
        /// </summary>
        public bool Attempted 
        { 
            get { return _attempted; } 
            set { _attempted = value; } 
        }

        /// <summary>
        /// Was this ImageShield successfully authenticated.
        /// </summary>
        public bool Authenticated 
        { 
            get { return _authenticated; } 
            set { _authenticated = value; } 
        }

        /// <summary>
        /// Raw XML string from which this ImageShield object was created.
        /// </summary>
        public string Xml 
        { 
            get { return _xml; } 
            set { _xml = value; } 
        }


        /// <summary>
        /// Generate an ImageShield instance from the provided XML.
        /// </summary>
        /// <remarks>
        /// <paramref name="xml"/> looks like this:
        /// <![CDATA[
        /// <imageshield>
        ///     <id>abc123</id>
        ///     <imageshield_length>2</imageshield_length>
        ///     <order_matters>False</order_matters>
        ///     <width>4</width>           
        ///     <height>3</height>         
        ///     <image_code_color>Red</image_code_color>
        ///     <imageURI>https://api.vidoop.com/vs/imageshields/abc123/image</imageURI>
        ///     <attempted>false</attempted>    
        ///     <authenticated>false</authenticated>
        ///     </imageshield>
        ///]]>
        /// </remarks>
        /// <param name="xml">A <see cref="System.String" /> containing the
        /// xml representation of an image shield.</param>
        /// <returns>An instance of a <see cref="VidoopSecure.ImageShield" />.</returns>
        /// <seealso cref="VidoopSecure" />
        static public ImageShield FromXml(string xml) 
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            return GenerateImageShieldFromXmlDocument(doc);
        }

        /// <summary>
        /// Generate an ImageShield instance from the XML in <paramref="stream" />.
        /// </summary>
        /// <remarks>
        /// <paramref name="xml"/> looks like this:
        /// <![CDATA[
        /// <imageshield>
        ///     <id>abc123</id>
        ///     <imageshield_length>2</imageshield_length>
        ///     <order_matters>False</order_matters>
        ///     <width>4</width>           
        ///     <height>3</height>         
        ///     <image_code_color>Red</image_code_color>
        ///     <imageURI>https://api.vidoop.com/vs/imageshields/abc123/image</imageURI>
        ///     <attempted>false</attempted>    
        ///     <authenticated>false</authenticated>
        ///     </imageshield>
        ///]]>
        /// </remarks>
        /// <param name="xml">A <see cref="System.String" /> containing the
        /// xml representation of an image shield.</param>
        /// <returns>An instance of a <see cref="VidoopSecure.ImageShield" />.</returns>
        /// <seealso cref="VidoopSecure" />
        static public ImageShield FromXml(Stream stream) 
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(stream);
            return GenerateImageShieldFromXmlDocument(doc);
        }

        static private ImageShield GenerateImageShieldFromXmlDocument(XmlDocument doc)
        {
            ImageShield shield = new ImageShield();
            shield.Xml = doc.OuterXml;
            shield.Id = doc.GetElementsByTagName("id")[0].InnerText;
            shield.Length = int.Parse(doc.GetElementsByTagName("imageshield_length")[0].InnerText);
            shield.OrderMatters = bool.Parse(doc.GetElementsByTagName("order_matters")[0].InnerText);
            shield.Width = int.Parse(doc.GetElementsByTagName("width")[0].InnerText);
            shield.Height = int.Parse(doc.GetElementsByTagName("height")[0].InnerText);
            shield.ImageCodeColor = doc.GetElementsByTagName("image_code_color")[0].InnerText;
            shield.Image = doc.GetElementsByTagName("imageURI")[0].InnerText;
            shield.Attempted = bool.Parse(doc.GetElementsByTagName("attempted")[0].InnerText);
            shield.Authenticated = bool.Parse(doc.GetElementsByTagName("authenticated")[0].InnerText);

            return shield;
        }
    }
}
